/// Bountiful Bevelled Buttons
--------------------------
By Andrew Porter
_
| \ountiful __________________________
|O/ _ An |\_________________________/|
| \ | \evelled Automated || ||
|O ||O/ _ Button || By ||
|_/ | \ | \uttons Library || Andrew Porter ||
|O ||O/ for the ||72134.2050@compuserve.com||
|_/ | \ Director ||_________________________||
|O | Version 2 |/_________________________\|
|_/
*** The Tool & Goal ***
The Director Version 2 is a powerful text based authoring
system for creating interactive multimedia presentations, slide
shows and animations. Yet, the strength of the program is also
its weakness. Although the process is easy, it needs some
programming skills and careful attention to details. One area
that could be streamlined is button creation for interactive
presentations.
Professional looking multimedia presentations usually have
3D bevelled buttons that are not hard to create but can be time
consuming create. The Director has a "Button Utility" to use with
pre-drawn graphics but no built-in button creation features...
yet, it does have a full list of graphic capabilities. The
following is an explanation of how to develop a button "library"
that will allow you to create a 3 dimensional looking bevelled
button within your Director script. The command will position,
size and colour a bevelled button and centre a text label on it.
You can even have an optional "button hole."
For those who don't use the Director as their authoring
system the BASIC language source could be easily translated to
the language of your choice. It could even be adapted for use
with ARexx capable paint & draw programs.
As you know, on-screen buttons are the main way to
navigate through an interactive presentation. Normally, with the
Director, an author would use a paint program to draw buttons,
save the image(s), and then load it into the Button Utility to
mark out the hotspot locations. This is an easy, largely
automated process.
Yet, there are a few potential problems with this method. If
you have many different screens of buttons, each one takes up
valuable disk space and waiting for it to load can slow down the
presentation. Also, using a paint program to draw buttons can be
time consuming and tedious, especially if you want to make many
revisions. The solution? Use the graphic capabilities of the
Director to render the buttons for you.
To render buttons on screen you could simply make a
rectangle and stick some text on it, though it wouldn't look very
elegant or professional. A powerful feature of the Director is
the external library. A library is frequently used pieces of
code that can be called up in any script with just a few
commands. The MakeButton command described here will render
buttons of any size at any location on any screen format. The
size of the bevel, the location of the text, the colours and
almost any feature can be modified with a few quick numbers.
*** The Essence of Buttonness ***
To get the impression of 3 dimensions, a button can have
light and dark areas around it that provide the illusion that it
is raised out from the screen. The bevelled look requires some
work because there are five facets (or sides) that include the
button top area, (the part that would be pressed) and four
trapezoid "sides" (two parallel lines joined by angled lines)
that appear to slope up from the screen surface to the edges of
the button top. Shading of the sides, or bevels, is done
according to an imaginary high, leftside light source. The bevels
on the top and left are brighter than the right and bottom
bevels. The use of colour and shades is what gives a button its
"buttonness."
Generally, the thicker the bevels the "higher" the button
appears (but, if the bevels get too large they loose the
illusion.) Also, bevels usually appear equal on all sides, as if
the button was looked at straight-on. One way to enhance the
look of a button is to place it in a "buttonhole," such as a
bevelled frame around the button with a slight gap between. This
gives the impression that the button is mounted on the screen and
inlaid into it. Usually the buttonhole bevels have the opposite
colour scheme to make it appear to be further away instead of
nearer. An author must have control over the thickness and
colour of button and hole bevels and the size and colour of the
gap.
Buttons without a label or picture would be quite useless.
Therefore, to note their function, buttons must have text or
pictures on them. For aesthetic reasons this information
probably should be centred or positioned in some way and should
appear to be apart of the button, ie. text should be constrained
to the button and wrap around inside it if needed. The author
also should be able to control the font, colour, indentation of
margins and other attributes of the text.
*** A Button Library ***
In general, an multimedia author needs to be concerned about
the three basic categories of location, size and colour.
Location includes the location of the button and the location of
the text within the button. Size is the size of the button, its
bevels, font size, and, if there is a buttonhole, the size of the
buttonhole gap and bevels. Colour includes the colour of button
elements and arrangement and text style and colour.
When developing a presentation an author will often have
one consistent style for the whole work and will only need to be
concerned with the button size, location, and label. Everything
else could be set once by default or a configuration setup.
Presented here, the Button Library has four main user
commands: "MakeButton" takes care of positioning, sizing and
labelling; "ButtonConfig" sets up bevel sizes and the existence
of a ButtonHole; "ButtonColour" sets the colours for all the
various parts; and "ButtonText" sets the font type and some text
attributes. There is also a command called "ButtonReset" to
restore the default values. Only MakeButton actually does
anything, the others simply assign variables. There are also
several other procedures in the library that are not directly
accessed.
*** The MakeButton Command ***
There are several ways to render bevels. One way is to
create the outline for each facet by drawing a line from one
point to another, resulting in a closed graphic, and fill it in
with the appropriate colour. This is similar to how it would be
done in a paint program. The Director has a built-in feature
that can do this more efficiently. Using the POLYGON command all
you have to do is feed the coordinates for each facet and the
program will render it. After doing this five times you have a
bevelled button.
Of course, you can't input any coordinates that you want,
you have to be systematic. A bevelled button is composed of two
rectangles, one inside the other for a total of eight corners or
points. The bevel ends are formed by drawing a line from one
inside point of the large rectangle to an opposing outside point
of the smaller graphic. All the points have a relationship to
each other by being equal, less or greater in value than the
others, depending on the location.
The MakeButton command uses the left/top corner coordinates
and the width and height of the button. A button that originates
at location 10,10; is 50 pixels wide and 25 pixels high and says
"Press Me" would use the command: DO MakeButton, 10, 10, 50, 25,
"Press Me". MakeButton uses the PARAMETER command to grab the
coordinates. It knows that the first two numbers represent the
location of the top corner (10,10) and the second two are width
and height (50,25). These values represent the outside edges of
the larger rectangle. The default thickness for bevels is 5
pixels, so the small inner rectangle can be calculated because it
is 5 pixels smaller on all sides.
I mentioned that there are a total of eight points to be
calculated. I have numbered these points P1 to P8 going
clockwise around and in from the left/top corner. The math is
very easy but a diagram explains it better than I can:
x = the starting x coordinate (left)
y = the starting y coordinate (top)
p# = the two x & y coordinates
p#x = the x coordinate of the p# point
p#y = the y coordinate of the p# point
bx = the bevel width
by = the bevel height
p1 _________________ p2 Outer Rectangle
|\_______________/| p1 = x & y
||p5 p6|| p2 = (x + width) & y
|| || p3 = (x + width) & (y + height)
|| || p4 = x & (y + height)
|| ||
|| || Inner Rectangle
||p8___________p7|| p5 = (p1x + bx) & (p1y + by)
|/_______________\| p6 = (p2x - bx) & (p2y + by)
p4 p3 p7 = (p3x - bx) & (p3y - by)
p8 = (p4x + bx) & (p4y - by)
The inner rectangle is calculated by using
the values in p1,p2,p3 & p4 and adding or
subtracting the bevel width or height, as required.
When calculating the coordinates, all values are in relation
to the origin that is considered temporarily to be 0,0 or the top
corner of the screen. This way the image could easily be moved
to any location on the screen. After completing the calculations
for the eight points the values are recorded in a 2 dimensional,
8 element array called "PointList". An array is a group of variables
accessed by a number instead of a name. When finished, we have the
relative location for all the points.
The next step is to draw the polygons. As I mentioned, an
array stores the eight points for the button numbered 1 to 8. To
draw each facet all that needs to be done is pass the point
number and colour to the POLYGON command for rendering. We are
not passing the actual coordinates, only its location in the
PointList array. We do this five times: the button top and four
bevels.
If a ButtonHole is to be drawn then it is be done first,
before drawing the button, using the same method as above. The
only difference is that the size has to be calculated to be
larger than the button, it also has inverted colours.
I should note that there is an internal procedure charged
with the dual purpose of setting bevel and gap variables and
adjusting for the screen format. Amiga screen formats have
different pixel aspects (the ratio of width to height) and can
distort images if not dealt with. Hires and Lores screen pixels
are almost square but Medres (640x200) and Interlace (320x400)
are double-high and double-wide, respectively. The Button library
will adjust for this distortion for the bevels so they will
appear to be the same thickness on all sides, regardless of
screen display format.
The last deed to be done is button labelling. All that is
required here is to calculate the margins of the button and use
an FTEXT command to write the label. The PointList array,
mentioned earlier, provides the margins that are then adjusted
for screen location and indentation. The result is that the text
will always wrap, left to right, in the button area. The
formating codes are inserted into the text string for use with
FTEXT. FTEXT outputs formatted text that can include colour,
font, style and justification changes. Therefore, the author can
use special codes to highlite the text.
The centre of the from top to bottom is calculated and is
then adjusted for the font height. If the author wants to have it
higher or lower then she or he can modify the FontHeight
parameter accordingly. With this feature the button library is
not limited to buttons, it also could be used to display text.
The source for this library may look long but if you use
buttons frequently you probably will find that the effort to
type it out is worth the convenience it provides. One word of
warning: unlike ARexx, the Director is CASE sensitive for
variable and procedure labels. When you type it out be VERY
careful to follow any mIXeD CAsE names. You also will note that
many variables have a "b" at the beginning. This is to protect
against name duplication within your script which could have
unexpected results. When you are finished save it as
Director:library/Button.dlib.
*** Button Things Up! ***
How to do you use this library? There are a couple steps
but it isn't too difficult. The first thing is to put INCLUDE
Director:library/Button.dlib" in your script, usually at the
top. To get a default button type:
DO MakeButton,<Xpos>,<Ypos>,<Width>,<Height>,<"Comment">
Then you have to set up the hotspot by adding the same
position/size parameters to your buttonlist array (see Director
manual, P11-3).
To change bevel thickness or the existence of a buttonhole
type: DO ButtonConfig,<BevSize>,<HoleBev>,<GapSize>,<Adjust>
BevSize is the bevel thickness, HoleBev is the buttonhole bevel
thickness & GapSize is the size of the gap. If HoleBev and
GapSize are both 0 no ButtonHole is drawn. Adjust turns screen
format adjustment OFF (0) or ON (1).
To change the colour you enter:
DO ButtonColours, <Top>,<Hilite>,<Shade1>,<Shade2>,<Shade3>,
<Dark>,<Text>,<TextBG>
Each parameter is a colour palette number. Top is the button
colour, Hilite is the top bevel, Shade1 to Shade3 are
respectively the right-side, bottom and left-side bevels, Dark is
the gap colour, Text is the text colour and TextBG is for the
text shadow.
To modify the text configuration use the command:
DO ButtonText, <FontNum>, <FontHeight>, <ShadowX>,
<ShadowY>, <LMargin>, <RMargin>, <Justify>, <Centre>
FontNum is a loaded font from 1-9, 0 makes no changes and 10
resets to default system font. FontHeight is the height in pixels
for the font, or the number of pixels text is to be offset from
the centre (divided by 2.) ShadowX & ShadowY are the text
background offset in pixels (NONE if 0). LMargin & RMargin are
the margins within the button. Ypos is the number of pixels down
from the top edge (will approximate the centre if 0), Justify and
Centre will each turn justification or centring ON (1) or OFF (0).
The script called ShowButtons shows how to use the button
library. Like most things, the best way to learn is to play
around. Enhancements of this library could include changable
text, rounded edges, automatic brush placement, display effects,
animation, etc. You could create a utility to save IFF pictures
to modify renderings in paint programs. Also, modification of the
Button Utility, that is included with the Director, could allow
you to interactively draw buttons, similar to a draw program. The
possiblities are almost endless if you want bountiful bevelled
buttons.
Copywrite 1993 Andrew Porter
ImagEYE Creations
;*** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE ***
;
;SAVE the following as "Director:Library/Button.dlib"
;Upto the next NOTE
;
;*** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE ***
;************************************************************
;* Button Library *
;* 1993 Andrew Porter, ImagEYE Creations *
;************************************************************
GOTO SkipButton : REM Skip library
/MakeButton:
REM Make Bevel Buttons
IF bSetup <> 1
DIM bButtonText[180] : REM Records button label
DIM bPointList[8,2],2 : REM Records button coordinates
DIM bPolyAry[9,2],2 : REM Records polygon coordinates
bSetup = 1 : REM Mark that arrays are setup
ENDIF
REM Get button location, size and text
PARAMETER bButLeft,bButTop,bButWidth,bButHeight,bButtonText$
REM Setup default colours, configuration and text format
IF bSetConfig<>1 THEN DO ButtonConfig,5,3,2,1
IF bSetColours<>1 THEN DO ButtonColours,14,1,2,3,4,0,1,0
IF bSetText<>1 THEN DO ButtonText,0,9,0,0,5,5,0,1
DO bScreenAdjust : REM Adjust for pixel aspect
REM Draw a button hole when bevel OR gap is given
IF (bHoleBevelX>0)|(bGapX>0) THEN DO bButtonHole
REM Calculate the bevel coordinates
DO bCalcBevel,bButLeft,bButTop,bButWidth,bButHeight,bButBevX,bButBevY
REM Draw bevelled button
DO bMakeBevel,bHiLite,bShadow2,bShadow3,bShadow1,bButtonClr
REM Put a label on button
DO bButtonLabel
RETURN
/ResetButton:
REM Resets button defaults
DO ButtonConfig,5,3,2,1
DO ButtonColours,14,1,2,3,4,0,1,0
DO ButtonText,0,9,0,0,5,5,0,1
RETURN
/ButtonConfig:
REM Assign button defaults
PARAMETER bButBev,bHoleBev,bGap,bAdjust
bSetConfig = 1 : REM Button defaults set
RETURN
/ButtonColours:
REM Assign button colours
PARAMETER bButtonClr,bHiLite,bShadow1,bShadow2
PARAMETER bShadow3,bDark,bTextClr,bDropColour
bSetColours = 1 : REM Colour defaults set
RETURN
/ButtonText:
REM Assign text configuration
PARAMETER bFontNum,bFontHeight,bShadowX,bShadowY
PARAMETER bLMargin,bRMargin,bJust,bCentre
bSetText = 1 : REM Text defaults set
RETURN
/bScreenAdjust:
REM Adjust for current screen pixel aspect
REM so bevels will appear equal on all sides
RESOLUTION outbuffer,bXres,bYres,bDepth
REM All sides are equal
bButBevX = bButBev : bButBevY = bButBev
bGapX = bGap : bGapY = bGap
bHoleBevX = bHoleBev : bHoleBevY = bHoleBev
IF bAdjust <> 1 THEN RETURN
IF (bXres >= 640) & (bYres < 400)
REM Buffer is likely MedRes, make pixels double wide
bButBevX = bButBev * 2
bGapX = bGap * 2
bHoleBevX = bHoleBev * 2
ENDIF
IF (bXres < 640) & (bYres >= 400)
REM Buffer is likely LoRes Interlace, make double high
bButBevY = bButBev * 2
bGapY = bGap * 2
bHoleBevY = bHoleBev * 2
ENDIF
RETURN
/bButtonHole:
REM Draw button hole for buttons which has inverted colour
REM Use outside edge of button to determine size
bHoleLeft = bButLeft - bGapX - bHoleBevX
bHoleTop = bButTop - bGapY - bHoleBevY
bHoleWidth = bButWidth+(bGapX * 2)+(bHoleBevX * 2)
bHoleHeight = bButHeight+(bGapY * 2)+(bHoleBevY * 2)
REM Calculate bevel for button hole
DO bCalcBevel,bHoleLeft,bHoleTop,bHoleWidth,bHoleHeight,bHoleBevX,bHoleBevY
REM Pass inverted colour scheme to button hole
DO bMakeBevel,bShadow3,bShadow1,bHiLite,bShadow2,bDark
RETURN
/bCalcBevel:
REM Calculate inside bevel co-ordinates
PARAMETER bLeft,bTop,bWidth,bHeight,bBevelX,bBevelY
REM Set origin at Left, Top corner of button
bPolyAry[1,1] = bLeft,bTop
REM Build point list starting top/left, clockwise & in.
bPointList[1,1] = 0,0
bPointList[2,1] = bWidth,0
bPointList[3,1] = bWidth,bHeight
bPointList[4,1] = 0,bHeight
bPointList[5,1] = bBevelX,bBevelY
bPointList[6,1] = (bWidth-bBevelX),bBevelY
bPointList[7,1] = (bWidth-bBevelX),(bHeight-bBevelY)
bPointList[8,1] = bBevelX,(bHeight-bBevelY)
RETURN
/bMakeBevel:
PARAMETER bTopClr,bRightClr,bBottomClr,bLeftClr,bDisplayClr
REM Draw each facet by passing point number & cols
DO bDrawBevels,bTopClr,1,2,6,5 : REM Top bevel
DO bDrawBevels,bRightClr,6,2,3,7 : REM Right bevel
DO bDrawBevels,bBottomClr,8,7,3,4 : REM Bottom bevel
DO bDrawBevels,bLeftClr,1,5,8,4 : REM Left bevel
DO bDrawBevels,bDisplayClr,5,6,7,8 : REM Button area
RETURN
/bDrawBevels:
REM Draw the bevelled button
bPolyAry[2,1] = 100,100
bPolyAry[4,1] = 4
PARAMETER bColour,bP1,bP2,bP3,bP4
bPolyAry[4,2] = bColour
REM Get point values from point numbers
bPolyAry[6,1] = bPointList[bP1,1],bPointList[bP1,2]
bPolyAry[7,1] = bPointList[bP2,1],bPointList[bP2,2]
bPolyAry[8,1] = bPointList[bP3,1],bPointList[bP3,2]
bPolyAry[9,1] = bPointList[bP4,1],bPointList[bP4,2]
POLYGON bPolyAry
RETURN
/bConvNumber:
REM Convert numbers to characters & retain all digits
PARAMETER tNumber,tPlaces
DIM convnum[13]
DIM tChar[2]
tDecimal = 1
FOR tCount = 1 TO (tPlaces-1)
tDecimal = tDecimal * 10
NEXT
FOR tCount = 1 TO tPlaces
tTempVal = tNumber/tDecimal
tDigit = tTempVal
tDigit = tDigit - ((tTempVal/10)*10)
convnum$[tCount] = tDigit
tDecimal = tDecimal/10
tOld = tDigit
NEXT
RETURN
/bButtonLabel:
DIM bBText[200] : REM Set up transfer string array
REM Convert colour num to 2 characters, returns convnum$
DO bConvNumber,bTextClr,2
STRING "|c";convnum$,bBText$,4 :REM Insert colour code
REM Get left margin for button
bStartX = bButLeft + bPointList[5,1] + bLMargin
DO bConvNumber,bStartX,3 :REM Convert to 3 characters
REM Insert left margin command
STRING "|ml";convnum$,bBText$[5],6
REM Get right margin, convert to characters and insert
bEndX = (bButLeft + bPointList[6,1])-bRMargin
DO bConvNumber,bEndX,3
STRING "|mr";convnum$;"|r1",bBText$[11],9
REM Has a font been loaded? Must be #1-9, 10
IF (bFontNum > 0) & (bFontNum <= 10)
REM Font 10 resets font to default
IF bFontNum = 10 THEN bFontNum = 0
STRING "|f";bFontNum;bButtonText$;"|t";bCentre;"|r1",bBText$[20],179
ELSE
STRING bButtonText$;"|t1|r1|t0",bBText$[20],179
ENDIF
REM Calculate label position
bStartY=(bPointList[8,2]-bPointList[5,2])/2+bButTop+bPointList[5,2]
bStartY=bStartY-(bFontHeight/2) :REM Adjust for LF
DRAWMODE 0
IF (bShadowX <> 0)|(bShadowY <> 0)
MOVE bStartX,(bStartY+bShadowY)
FTEXT bJust,bBText$,bDropColour,bShadowX
ENDIF
MOVE bStartX,bStartY
FTEXT bJust,bBText$
DRAWMODE 1
RETURN
/SkipButton:
;CopyWrite 1993 Andrew Porter
;May be copied for NON-COMMERCIAL uses
;All Right Reserved
;ImagEYE Creations
;*** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE ***
;
;SAVE the preceding as "Director:Library/Button.dlib"
;SAVE the following in a separate file and run using the director
;
;*** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE ***
;***********************************************************
;* ShowButton 1993 Andrew Porter *
;* A demonstration of the Bevelled Button Library *
;***********************************************************
REM Load library
INCLUDE "Director:Library/Button.dlib"
REM Load a special font
LOADFONT,1,16,"Garnet.font"
NEW 640,200,4 :REM Open 16 colour hires screen
REM Set colours 0-4 as shades of grey
color 0,0,0,0
color 1,14,14,14
color 2,12,12,12
color 3,9,9,9
color 4,6,6,6
REM Display title
CENTER ON : SETFONT 1 : MOVE 0,20 : PEN 15
TEXT "A demonstration of the Bevelled Button Library"
SETFONT 0 : CENTER OFF
REM First a default
DO MakeButton,25,40,150,50,"Default BUTTON"
REM Now Change the bevel size
DO ButtonConfig,2,5,5,1
DO MakeButton,230,45,150,30,"New Bevel Sizes"
REM Now get rid of the button hole and screen adjustment
REM Notice how side bevels are not as thick
DO ButtonConfig,5,0,0,0
DO MakeButton,410,35,225,50,"No hole, No adjust"
REM Now reset to defaults and change colours
DO ResetButton
DO ButtonColours,3,2,2,4,4,0,6,0
DO MakeButton,25,110,150,50,"New Colours"
REM Now change the Font attributes
DO ButtonText,1,20,2,1,2,2,0,1
DO MakeButton,200,110,240,75,"New Font & Backgound"
REM Now change the Font attributes
DIM ReadText[200]
ReadText$ = "This is an example of wrapped
text in a button. This could be used to
give instructions however it is limited
to 170 characters."
REM Reset font, move to top, and turn centring off
DO ResetButton
DO ButtonText,10,75,0,0,2,2,0,0
DO MakeButton,470,100,160,90,ReadText$
REM Show Exit
DO ResetButton
DO MakeButton,25,175,150,20,"LMB to Exit"
/EndlessPause:
goto EndlessPause
converted with guide2html by Kochtopf